package cn.thr.ymcc.service.impl;

import cn.thr.ymcc.CourseDoc;
import cn.thr.ymcc.client.SearchClient;
import cn.thr.ymcc.constant.Cos;
import cn.thr.ymcc.domain.*;
import cn.thr.ymcc.dto.CourseDto;
import cn.thr.ymcc.dto.MessageDto;
import cn.thr.ymcc.mapper.*;
import cn.thr.ymcc.result.JsonResult;
import cn.thr.ymcc.service.ICourseService;
import cn.thr.ymcc.util.AssertUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author thr
 * @since 2023-02-28
 */
@Slf4j
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course> implements ICourseService {

    @Autowired
    private TeacherMapper teacherMapper;

    @Autowired
    private CourseDetailMapper courseDetailMapper;

    @Autowired
    private CourseMarketMapper courseMarketMapper;

    @Autowired
    private CourseSummaryMapper courseSummaryMapper;

    @Autowired
    private CourseResourceMapper courseResourceMapper;

    @Autowired
    private CourseTypeMapper courseTypeMapper;

    @Autowired
    private SearchClient searchClient;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    /**
     *  新增课程
     *  课程主表
     *  课程详情表
     *  课程市场营销表
     *  课程统计表
     *  课程课件资源表
     *  课程与讲师的中间表
     * @param courseDto
     */
    @Transactional
    @Override
    public void save(CourseDto courseDto) {
        //1.保存课程主表信息
        Course course = courseDto.getCourse();
        //课程的讲师名称
        //讲师的id 不等于空 合作 不等与0
        if (courseDto.getTeacharIds() != null && !courseDto.getTeacharIds().isEmpty()){
            //就根据courseDto.getTeacharIds() 取数据库查询数据
            List<Teacher> teachers = teacherMapper.selectBatchIds(courseDto.getTeacharIds());
            //teachers 里就有讲师的id   stream()变成流用id查询，map带着id去查寻名字  Collectors.toList()用来结束Stream流
            List<String> teacherName = teachers.stream().map(teacher -> teacher.getName()).collect(Collectors.toList());
            //把老师的名字设置进去
            course.setTeacherNames(String.join(",",teacherName));
        }
        //添加进去
        baseMapper.insert(course);

        //2.保存课程详细信息
        CourseDetail courseDetail = courseDto.getCourseDetail();
        courseDetail.setId(course.getId());
        courseDetailMapper.insert(courseDetail);

        //3.保存课程市场营销表
        CourseMarket courseMarket = courseDto.getCourseMarket();
        courseMarket.setId(course.getId());
        courseMarketMapper.insert(courseMarket);

        //4.课程统计表
        CourseSummary courseSummary = new CourseSummary();
        courseSummary.setId(course.getId());
        courseSummaryMapper.insert(courseSummary);

        //5.课程课件资源表
        //判断可以是否不为空和为0
        if(courseDto.getZipResources() !=null && !courseDto.getZipResources().isEmpty()){
            for(String zipResources : courseDto.getZipResources()){
                CourseResource courseResource = new CourseResource();
                //连接外键id
                courseResource.setCourseId(course.getId());
                //文件的地址
                courseResource.setResources(zipResources);
                courseResourceMapper.insert(courseResource);
            }
        }
        //6.课程与讲师的中间表
        //判断可以是否不为空和为0 由于我们没有生成中间表，必须自己写【写在courseMapper或者TeacherMapper 里面】
        if(courseDto.getTeacharIds() != null && courseDto.getTeacharIds().isEmpty()){
            //批量保存课程与讲师中间表的数据
            baseMapper.insertBatchCourseTeacher(course.getId(),courseDto.getTeacharIds());
        }
    }
    @Transactional
    @Override
    public void updateById(CourseDto courseDto) {



    }
    /**
     * 课程编辑：回显数据【课程详情、课程市场营销、统计信息、课程所属类别、课程的讲师id集合、课程的资源集合】
     * @param courseId
     * @return
     */
    @Override
    public Map<String, Object> getDettailById(Long courseId) {
        //把courseId 查出来
        Course course = baseMapper.selectById(courseId);
        CourseDetail courseDetail = courseDetailMapper.selectById(courseId);
        CourseMarket courseMarket = courseMarketMapper.selectById(courseId);
        CourseSummary courseSummary = courseSummaryMapper.selectById(courseId);
        CourseType courseType = courseTypeMapper.selectById(course.getCourseTypeId());
        List<Long> teacherIds = baseMapper.selectCourseTeacherIds(courseId);
        List<CourseResource> resourceList = courseResourceMapper.selectList(new QueryWrapper<CourseResource>().eq("course_id", courseId));

        //创建一个HashMap 把查到的数据全部添加进去
        Map<String,Object> map = new HashMap<>();
        map.put("courseDetail",courseDetail);
        map.put("courseMarket",courseMarket);
        map.put("courseSummary",courseSummary);
        map.put("courseType",courseType);
        map.put("teacherIds",teacherIds);
        map.put("resourceList",resourceList);

        return map;
    }
    /**
     * 课程发布上线
     * @param courseList
     * @return
     */
    @Transactional
    @Override
    public JsonResult onLineCourse(List<Course> courseList) {
        //校验数据 ：用户勾选的课程不能包含上线的
        //把数组变成一个流，进行过滤 把1的筛选出来
        List<Course> courseseOnLine = courseList.stream().filter(course -> course.getStatus() == 1).collect(Collectors.toList());
        //用工具类判断是不是为空
        AssertUtil.isTrue(courseseOnLine ==null || courseseOnLine.isEmpty(),"对不起哦，里面包含了上线课程，请重新选择！");

        //2. 修改 1）可以一个一个的循环修改 也可以写个批量修改
        for (Course course : courseList) {
            course.setStatus(1);
            course.setOnlineTime(new Date());
            baseMapper.updateById(course);
        }

        //openfeign 调用全文检查服务接口
        List<CourseDoc> courseDocs = courseList.stream().map(course -> course2Doc(course)).collect(Collectors.toList());
        JsonResult jsonResult = searchClient.saveBatch(courseDocs);
        AssertUtil.isTrue(jsonResult.getSuccess(),jsonResult.getMessage());

        /**
         * 4.消息推送【锦上添花的功能，不重要，允许消息消息丢失，起到一个推广的作用】
         * 1）三种消息：邮件、短信、站内信
         * 2）消息内容：亲爱的Xxx用户，你好！您关注的XXXX课程发布上线了，请点击xxxxxx链接获取最新资讯。
         * 3）发给谁？推送给关注过同类型课程的用户
         *  首先根据当前上线的课程的所属类别查询同类别的课程id；
         *  然后根据这些课程id查询收藏记录表，得到用户id；
         *  最后openfeign：根据这些用户id查询用户表，得到他们的手机号和邮箱；
         */

//        MessageDto messageDto = new MessageDto();
//        messageDto.setTitie("课程发布");
//        //课程名称
//        List<String> courseName = courseList.stream().map(course -> course.getName()).collect(Collectors.toList());
//
//        messageDto.setContent("亲爱的用户您好，最新课程 <a href='测试'> "+String.join("，", courseName)+" </a> 发布啦，点击课程了解详情");
//
//        //发送手机号
//        messageDto.setSmsDtoList(Arrays.asList(
//                new MessageDto.SmsDto(1L,"15397691230",null),
//                new MessageDto.SmsDto(1L,"15397691231",null)
//        ));
//
//        //发送邮件
//        messageDto.setEmailDotList(Arrays.asList(
//                new MessageDto.EmailDot(1L, "1741115987@qq.com", null),
//                new MessageDto.EmailDot(2L, "1741115986@qq.com", null),
//                new MessageDto.EmailDot(3L, "1741115985@qq.com", null)
//        ));
//
//        //站类消息
//        messageDto.setStationDotList(Arrays.asList(
//                new MessageDto.StationDto(1L, "系统消息"),
//                new MessageDto.StationDto(2L, "系统消息"),
//                new MessageDto.StationDto(3L, "系统消息")
//        ));
//        Message<String> message = MessageBuilder.withPayload(JSON.toJSONString(messageDto)).build();
//        rocketMQTemplate.sendOneWay(
//                Cos.Message.TOPIC_MESSAGE+":"+Cos.Message.TAGS_MESSAGE_SMS,
//                message
//        );
//        //发邮件
//        rocketMQTemplate.sendOneWay(
//                Cos.Message.TOPIC_MESSAGE+":"+Cos.Message.TAGS_MESSAGE_EMAIL,
//                message
//        );
//        //发站内信
//        rocketMQTemplate.sendOneWay(
//                Cos.Message.TOPIC_MESSAGE+":"+Cos.Message.TAGS_MESSAGE_STATION,
//                message
//        );

        return JsonResult.me();
    }

    /**
     * 给我一个course 对象，返回一个CourseDoc
     * @param course
     * @return
     */
    private CourseDoc course2Doc(Course course) {
        CourseDoc courseDoc = new CourseDoc();
        //复制实体类
        BeanUtils.copyProperties(course,courseDoc);
        //查询课程类别
        CourseType courseType = courseTypeMapper.selectById(course.getCourseTypeId());
        courseDoc.setCourseTypeName(courseType.getName());

        //date 转时间戳
        courseDoc.setStartTime(course.getStartTime().getTime());
        courseDoc.setOnlineTime(System.currentTimeMillis());
        courseDoc.setEndTime(course.getEndTime().getTime());

        //课程详情
        CourseDetail courseDetail = courseDetailMapper.selectById(course.getId());
        BeanUtils.copyProperties(courseDetail,courseDoc);

        //课程市场营销
        CourseMarket courseMarket = courseMarketMapper.selectById(course.getId());
        BeanUtils.copyProperties(courseMarket,courseDoc);
        courseDoc.setPrice(courseMarket.getPrice().doubleValue());
        courseDoc.setPriceOld(courseMarket.getPriceOld().doubleValue());

        //课程统计信息
        CourseSummary courseSummary = courseSummaryMapper.selectById(course.getId());
        BeanUtils.copyProperties(courseSummary,courseDoc);

        return courseDoc;
    }
}
